home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / util / pack / codecs_library.lha / Codecs / iff_rw.c < prev    next >
C/C++ Source or Header  |  1999-04-08  |  11KB  |  357 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <libraries/dos.h>
  4. #include <libraries/iffparse.h>
  5. #include <graphics/gfx.h>
  6. #include <utility/tagitem.h>
  7. #include <proto/exec.h>
  8. #include <proto/dos.h>
  9. #include <proto/graphics.h>
  10. #include <proto/iffparse.h>
  11. #include <utility/utility.h>
  12. #include <utility/tagitem.h>
  13.  
  14. /* Includes needed to use the codecs.library and the codecs */
  15. #include <libraries/codecs.h>
  16. #include <proto/codecs.h>
  17. #include <codecs/sp.h>
  18. #include <codecs/byterun.h>
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23.  
  24. #include "iff_rw.h"
  25.  
  26. #define ID_ILBM MAKE_ID('I','L','B','M')
  27. #define ID_BODY MAKE_ID('B','O','D','Y')
  28. #define ID_BMHD MAKE_ID('B','M','H','D')
  29. #define ID_CMAP MAKE_ID('C','M','A','P')
  30.  
  31. #define NUM_STOP_CHUNKS 3
  32.  
  33. #define SET_TAGITEM(tagitem, tag, data)  (tagitem).ti_Tag = (tag); (tagitem).ti_Data = (ULONG)(data)
  34.  
  35. struct Library *UtilityBase;
  36. struct Library *CodecsBase;
  37.  
  38. static int ReadBody(struct IFFHandle *iff, BitMapHeader *bmhd, struct BitMap *bm, ULONG Size)
  39. {
  40.     UBYTE *body;
  41.     Codec *MyCodec = NULL;
  42.     struct TagItem TagList[5];
  43.  
  44.  
  45.     if ((body = malloc(Size)) == NULL)
  46.     {
  47.        printf("Could not alloc body: %ld\n", Size);
  48.        return FALSE;
  49.     }
  50.     ReadChunkBytes(iff, body, Size);
  51.  
  52.     printf("Compressed Size: %ld\n", Size);
  53.     printf("Bytes per Row = %d\n", bm->BytesPerRow);
  54.  
  55.     /* Crete Codec to decode image */
  56.     switch (bmhd->compression)
  57.     {
  58.         case 0:  printf("This ILBM picture is not compressed (not supported yet)\n"); break;
  59.         case 1:  MyCodec = NewCodec("byterun.codec", 0); printf("Byterun codec\n");   break;
  60.         case 2:  MyCodec = NewCodec("sp.codec", 0); printf("S+P Wavelet codec\n");    break;
  61.         default: printf("Unsupported coding method for ILBM picture\n");              break;
  62.     }
  63.  
  64.     if (MyCodec)
  65.     {
  66.         SET_TAGITEM(TagList[0], CA_SRC_HANDLE, body);
  67.         SET_TAGITEM(TagList[1], CA_SRC_SIZE,   Size);
  68.         SET_TAGITEM(TagList[2], CA_IMAGEWIDTH, bmhd->w);
  69.         SET_TAGITEM(TagList[3], CA_DST_HANDLE, bm);
  70.         SET_TAGITEM(TagList[4], TAG_END,       0);
  71.  
  72.         Decode(MyCodec, TagList);
  73.  
  74.         DisposeCodec(MyCodec);
  75.  
  76.         printf("Decompressed %d bytes to %d bytes\n", Size, bm->BytesPerRow * bm->Rows * bm->Depth);
  77.     }
  78.     else
  79.     {
  80.         printf("Could not create Codec object\n");
  81.     }
  82.  
  83.     free(body);
  84.  
  85.     return TRUE;
  86. }
  87.  
  88. static LONG SaveBODY(struct IFFHandle *iff, BitMapHeader *bmhd, struct BitMap *bm)
  89. {
  90.     struct TagItem TagList[5];
  91.     ULONG  BufSize = 65536;
  92.     LONG   Size;
  93.     LONG   ReturnValue;
  94.     UBYTE *Buffer;
  95.     Codec *MyCodec = NULL;
  96.  
  97.     Buffer = malloc(BufSize);
  98.  
  99.     if (Buffer)
  100.     {
  101.         switch (bmhd->compression)
  102.         {
  103.             case 0:  printf("This ILBM BODY is not compressed (not supported yet)\n"); break;
  104.             case 1:  MyCodec = NewCodec("byterun.codec", 0L); break;
  105.             case 2:  MyCodec = NewCodec("sp.codec", 0L);      break;
  106.             default: printf("Unknown compression method\n");  break;
  107.         }
  108.  
  109.         if (MyCodec)
  110.         {
  111.             PushChunk(iff, ID_ILBM, ID_BODY, IFFSIZE_UNKNOWN);
  112.  
  113.             SET_TAGITEM(TagList[0], CA_DST_HANDLE, Buffer);
  114.             SET_TAGITEM(TagList[1], CA_DST_SIZE,   BufSize);
  115.             SET_TAGITEM(TagList[2], CA_IMAGEWIDTH, bmhd->w);
  116.             SET_TAGITEM(TagList[3], CA_SRC_HANDLE, bm);
  117.             SET_TAGITEM(TagList[4], TAG_END,       0);
  118.  
  119.             Size        = BufSize;
  120.             ReturnValue = 0;
  121.  
  122.             while (Size == BufSize)
  123.             {
  124.                 Size = Encode(MyCodec, TagList);
  125.                 if (Size > 0)
  126.                 {
  127.                     if (WriteChunkBytes(iff, Buffer, Size) != Size)
  128.                     {
  129.                         printf("Could not write to IFF chunk BODY\n");
  130.                         ReturnValue = -4L;
  131.                         break;
  132.                     }
  133.                     else
  134.                     {
  135.                         ReturnValue += Size;
  136.                         printf("Encoded %d bytes (total = %d)\n", Size, ReturnValue);
  137.                     }
  138.                 }
  139.                 else
  140.                 {
  141.                     printf("Problem %d in encoder", Size);
  142.                     ReturnValue = -3L;
  143.                     break;
  144.                 }
  145.             }
  146.             PopChunk(iff);
  147.             DisposeCodec(MyCodec);
  148.         }
  149.         else
  150.         {
  151.             ReturnValue = -2L;
  152.         }
  153.         free(Buffer);
  154.     }
  155.     else
  156.     {
  157.         ReturnValue = -1L;
  158.     }
  159.  
  160.     return ReturnValue;
  161. }
  162.  
  163.  
  164.  
  165. BOOL LoadILBM(char *filename, BitMapHeader *bmhd, BYTE **cmap, struct BitMap **bm)
  166. {
  167.     struct IFFHandle *iff;
  168.     struct ContextNode *cn;
  169.     LONG StopChunkArray[NUM_STOP_CHUNKS*2] = { ID_ILBM, ID_BMHD,
  170.                                                ID_ILBM, ID_CMAP,
  171.                                                ID_ILBM, ID_BODY
  172.                                              };
  173.     LONG   error;
  174.  
  175.     *cmap = NULL;
  176.     *bm   = NULL;
  177.  
  178.  
  179.     if ((CodecsBase  = OpenLibrary("codecs.library", 0L)))
  180.     {
  181.         if ((UtilityBase = OpenLibrary(UTILITYNAME, 0L)))
  182.         {
  183.             if ((IFFParseBase = OpenLibrary("iffparse.library", 0L)))
  184.             {
  185.                 if ((iff = AllocIFF()) != NULL)
  186.                 {
  187.                     if ((iff->iff_Stream = (ULONG)Open(filename, MODE_READWRITE)) != NULL)
  188.                     {
  189.                         InitIFFasDOS(iff);
  190.                         OpenIFF(iff, IFFF_READ);
  191.  
  192.                         if ((error = StopChunks(iff, StopChunkArray, NUM_STOP_CHUNKS)))
  193.                         {
  194.                             printf("error with StopChunk (%d)\n", error);
  195.                             return FALSE;
  196.                         }
  197.  
  198.                         for (;;)
  199.                         {
  200.                             error = ParseIFF(iff, IFFPARSE_SCAN);
  201.  
  202.                             if (error == IFFERR_EOF)
  203.                                 break;
  204.  
  205.                             if (error)
  206.                             {
  207.                                 printf("Error during parse %d\n", error);
  208.                                 return FALSE;
  209.                             }
  210.  
  211.                             cn = CurrentChunk(iff);
  212.                             if ((cn) && (cn->cn_Type == ID_ILBM))
  213.                             {
  214.                                 switch (cn->cn_ID)
  215.                                 {
  216.                                     case ID_BMHD:
  217.                                         ReadChunkBytes(iff, bmhd, sizeof(*bmhd));
  218.                                         printf("Size:        %d x %d\n", bmhd->w, bmhd->h);
  219.                                         printf("Planes:      %d\n", bmhd->nPlanes);
  220.                                         printf("Compression: %d\n", bmhd->compression);
  221.                                         break;
  222.  
  223.                                     case ID_CMAP:
  224.                                         *cmap = malloc(cn->cn_Size);
  225.                                         if (*cmap)
  226.                                         {
  227.                                             ReadChunkBytes(iff, *cmap, cn->cn_Size);
  228.                                         }
  229.                                         else
  230.                                         {
  231.                                             printf("Couldn't alloc memory for ColorMap\n");
  232.                                         }
  233.                                         break;
  234.  
  235.                                     case ID_BODY:
  236.                                         *bm = AllocBitMap(bmhd->w, bmhd->h, bmhd->nPlanes, BMF_CLEAR, NULL);
  237.                                         ReadBody(iff, bmhd, *bm, cn->cn_Size);
  238.                                         break;
  239.                                 }
  240.                             }
  241.                         }
  242.  
  243.                         CloseIFF(iff);
  244.                         Close(iff->iff_Stream);
  245.                     }
  246.                     FreeIFF(iff);
  247.                 }
  248.                 else
  249.                 {
  250.                    printf("Couldn't alloc iff handle\n");
  251.                 }
  252.  
  253.                 CloseLibrary(IFFParseBase);
  254.             }
  255.             else
  256.